package com.bz.xtcx.manager.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.bz.xtcx.manager.entity.*;
import com.bz.xtcx.manager.enums.UserTypeEnum;
import com.bz.xtcx.manager.mapper.BusUserMapper;
import com.bz.xtcx.manager.mapper.SysMenuMapper;
import com.bz.xtcx.manager.mapper.SysRoleMapper;
import com.bz.xtcx.manager.mapper.SysUserMapper;
import com.bz.xtcx.manager.service.IEmailService;
import com.bz.xtcx.manager.service.ISysUserService;
import com.bz.xtcx.manager.utils.ExcelUtil;
import com.bz.xtcx.manager.utils.SmsSender;
import com.bz.xtcx.manager.utils.WzEncryptUtil;
import com.bz.xtcx.manager.utils.WzStrUtil;
import com.bz.xtcx.manager.vo.VoPwd;
import com.bz.xtcx.manager.vo.VoQuery;
import com.bz.xtcx.manager.vo.VoResponse;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.jms.Destination;
import javax.servlet.http.HttpSession;
import java.io.OutputStream;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class SysUserService extends BaseService implements ISysUserService {
    
    @Autowired
    private SysUserMapper sysUserMapper;
    
    @Autowired
    private BusUserMapper busUserMapper;
    
    @Autowired
    private SysRoleMapper sysRoleMapper;
    
    @Autowired
    private SysMenuMapper sysMenuMapper;
    
    @Autowired
    private IEmailService emailService;

    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

    @Autowired
    private Destination refUserMeetingQueue;

    @Autowired
    private SmsSender smsSender;

    @Value("${wzsetting.activate-server}")
    private String activateServer;

    @Value("${wzsetting.def-pwd}")
    private String defUPwd;

    @Value("${wzsetting.aes-key}")
    private String defAesKey;

    @Value("${wzsetting.aes-iv}")
    private String defAesIv;

    @Value("${wzsetting.aes-algorithm-str}")
    private String defAesAlgorithmStr;

    @Value("${wzsetting.login-forbid-time}")
    private long defLoginForbidTime;

    @Override
    public int updateUserStatus(SysUser user) {
        SysUser oldUser = sysUserMapper.findById(user.getId());
        if(oldUser != null && !oldUser.getStatus().equals(user.getStatus())) {
            oldUser.setStatus(user.getStatus());
            return sysUserMapper.update(oldUser);
        }
        return 0;
    }
    
    @Override
    public int updateUserStatus(BusUser user) {
        BusUser oldUser = busUserMapper.findById(user.getId());
        if(oldUser != null && !oldUser.getStatus().equals(user.getStatus())) {
            oldUser.setStatus(user.getStatus());
            return busUserMapper.update(oldUser);
        }
        return 0;
    }
    
    @Override
    public VoResponse updateUserPwd(VoPwd vo) {
        VoResponse voRes = new VoResponse();
        User u = this.getUser();
        if(u.getUserType() == 0 || u.getUserType() == 101 || u.getUserType() == 102 || u.getUserType() == 103) {
            SysUser user = sysUserMapper.findById(u.getUserId());
            String md5Password = DigestUtils.md5DigestAsHex(vo.getPassword().getBytes());
            if(user.getPassword().equals(md5Password)) {
                md5Password = DigestUtils.md5DigestAsHex(vo.getNewPassword().getBytes());
                user.setPassword(md5Password);
                sysUserMapper.updatePwd(user);
            }else {
                voRes.setFail(voRes);
                voRes.setMessage("密码错误");
            }
        }else {
            BusUser busUser = busUserMapper.findById(u.getUserId());
            String md5Password = DigestUtils.md5DigestAsHex(vo.getPassword().getBytes());
            if(busUser.getPassword().equals(md5Password)) {
                md5Password = DigestUtils.md5DigestAsHex(vo.getNewPassword().getBytes());
                busUser.setPassword(md5Password);
                busUserMapper.updatePwd(busUser);
            }else {
                voRes.setFail(voRes);
                voRes.setMessage("密码错误");
            }
        }
        return voRes;
    }
    
    @Override
    public VoResponse lookUserPwd(VoPwd vo) {
        VoResponse voRes = new VoResponse();
        Object obj = this.getRedisTemplate().opsForValue().get("ecc:" + vo.getEmail());
        if(obj != null) {
            if(obj.toString().equals(vo.getCode())) {
                BusUser user = busUserMapper.findByEmail(vo.getEmail());
                if (null == user) {
                    voRes.setFail(voRes);
                    voRes.setMessage("邮箱在平台中未使用，重置失败");
                    return voRes;
                }
                String md5Password = DigestUtils.md5DigestAsHex(vo.getNewPassword().getBytes());
                user.setPassword(md5Password);
                busUserMapper.updatePwd(user);
                this.getRedisTemplate().delete("ecc:" + vo.getEmail());
                return voRes;
            }
        }else {
            obj = this.getRedisTemplate().opsForValue().get("mcc:" + vo.getCellphone());
            if(obj != null) {
                if(obj.toString().equals(vo.getCode())) {
                    BusUser user = busUserMapper.findByCellphone(vo.getCellphone());
                    if (null == user) {
                        voRes.setFail(voRes);
                        voRes.setMessage("手机号码在平台中未使用，重置失败");
                        return voRes;
                    }
                    String md5Password = DigestUtils.md5DigestAsHex(vo.getNewPassword().getBytes());
                    user.setPassword(md5Password);
                    busUserMapper.updatePwd(user);
                    this.getRedisTemplate().delete("mcc:" + vo.getCellphone());
                    return voRes;
                }
            }
        }
        voRes.setFail(voRes);
        voRes.setMessage("重置密码错误");
        return voRes;
    }

    @Override
    public VoResponse setDefUserPwd(VoPwd vo) {
        VoResponse voRes = new VoResponse();
        BusUser user = busUserMapper.findById(vo.getId());
        String usedDefUPwd = defUPwd;
        if (WzStrUtil.isBlank(defUPwd)) {
            usedDefUPwd = "123456";
        }
        String md5Password = DigestUtils.md5DigestAsHex(usedDefUPwd.getBytes());
        user.setPassword(md5Password);
        busUserMapper.updatePwd(user);
        return voRes;
    }

    @Override
    public VoResponse lookAdminPwd(VoPwd vo) {
        VoResponse voRes = new VoResponse();
        Object obj = this.getRedisTemplate().opsForValue().get("mcc:" + vo.getCellphone());
        if(obj != null) {
            if(obj.toString().equals(vo.getCode())) {
                SysUser user = sysUserMapper.findByUserame(vo.getUserName());
                if (null == user || !user.getCellphone().equals(vo.getCellphone())) {
                    voRes.setFail(voRes);
                    voRes.setMessage("账户或手机号码错，重置失败");
                    return voRes;
                }
                String md5Password = DigestUtils.md5DigestAsHex(vo.getNewPassword().getBytes());
                user.setPassword(md5Password);
                sysUserMapper.updatePwd(user);
                this.getRedisTemplate().delete("mcc:" + vo.getCellphone());
                return voRes;
            }
        }
        voRes.setFail(voRes);
        voRes.setMessage("重置密码错误");
        return voRes;
    }

    @Override
    public VoResponse updateUser(VoPwd vo) {
        VoResponse voRes =  new VoResponse();
        User u = this.getUser();
        if (null == u) {
            voRes.setFail(voRes);
            voRes.setMessage("您未登录或登录已超时，请重新登录");
            return voRes;
        }
        if (null != vo.getNeedModifyEmail() && vo.getNeedModifyEmail()) {
            Object obj = this.getRedisTemplate().opsForValue().get("ecc:" + vo.getEmail());
            if(obj != null) {
                if(obj.toString().equals(vo.getCode1())) {
                    this.getRedisTemplate().delete("ecc:" + vo.getEmail());
                    if(sysUserMapper.findByEmail(vo.getEmail()) != null || busUserMapper.findByEmail(vo.getEmail()) != null) {
                        voRes.setFail(voRes);
                        voRes.setMessage("邮箱已经被绑定");
                        return voRes;
                    }
                }else {
                    voRes.setFail(voRes);
                    voRes.setMessage("邮箱验证码错误");
                    return voRes;
                }
            }else {
                voRes.setFail(voRes);
                voRes.setMessage("请输入邮箱验证码");
                return voRes;
            }
        }
        if (null != vo.getNeedModifyMobile() && vo.getNeedModifyMobile()) {
            Object obj = this.getRedisTemplate().opsForValue().get("mcc:" + vo.getCellphone());
            if(obj != null) {
                if(obj.toString().equals(vo.getCode2())) {
                    this.getRedisTemplate().delete("mcc:" + vo.getCellphone());
                    if(sysUserMapper.findByCellphone(vo.getCellphone()) != null || busUserMapper.findByCellphone(vo.getCellphone()) != null) {
                        voRes.setFail(voRes);
                        voRes.setMessage("手机号码已经被绑定");
                        return voRes;
                    }
                }else {
                    voRes.setFail(voRes);
                    voRes.setMessage("手机验证码错误");
                    return voRes;
                }
            }else {
                voRes.setFail(voRes);
                voRes.setMessage("请输入手机验证码");
                return voRes;
            }
        }
        if (0 == u.getUserType() || 101 == u.getUserType() || 102 == u.getUserType() || 103 == u.getUserType()) {

            SysUser old = sysUserMapper.findById(u.getUserId());
            if (null != vo.getNeedModifyEmail() && vo.getNeedModifyEmail()) {
                old.setEmail(vo.getEmail());
            }
            if (null != vo.getNeedModifyMobile() && vo.getNeedModifyMobile()) {
                old.setCellphone(vo.getCellphone());
            }
            //old.setUserName(u.getUserName());
            old.setUpdater(u.getUserName());
            sysUserMapper.update(old);
        } else {
            BusUser old = busUserMapper.findById(u.getUserId());
            if (null != vo.getNeedModifyEmail() && vo.getNeedModifyEmail()) {
                old.setEmail(vo.getEmail());
            }
            if (null != vo.getNeedModifyMobile() && vo.getNeedModifyMobile()) {
                old.setCellphone(vo.getCellphone());
            }
            if (!old.getName().equals(vo.getName())) {
                old.setName(vo.getName());
            }
            old.setUpdater(u.getUserName());
            //old.setUserName(u.getUserName());
            busUserMapper.update(old);
            List<SysRole> roles = old.getRoles();
            if(roles != null && roles.size() > 0) {//add role
                busUserMapper.delUserRoles(old.getId());
                busUserMapper.addUserRoles(old);
            }
        }
        voRes.setMessage("账户信息更新成功");
        return voRes;
    }

    @Override
    public Object getUserInfo() {
        User u = this.getUser();
        if(u.getUserType() == 0) {
            return sysUserMapper.findById(u.getUserId());
        }
        BusUser user = busUserMapper.findById(u.getUserId());
        return user;
    }
    
    @Override
    public VoResponse sendEmailCode(String email) {
        VoResponse reVo = new VoResponse();
    	User user = this.getUser();
    	if(user == null) {
    		//验证存在的邮箱用户
    		BusUser bu = busUserMapper.findByEmail(email);
    		if (null == bu) {
    		    SysUser su = sysUserMapper.findByEmail(email);
                if (null == su) {
                    reVo.setFail(reVo);
                    reVo.setMessage("该邮箱未在平台使用，请尝试短信重置密码");
                    return reVo;
                }
    		}
    	}
        String id = String.valueOf((int)((Math.random()*9+1)*1000));
        if(emailService.sendCodeEmail(email, id)) {
            this.getRedisTemplate().opsForValue().set("ecc:" + email, id, 360, TimeUnit.SECONDS);
            reVo.setMessage("邮箱验证码已发送，请登录邮箱获取");
            return reVo;
        }
        reVo.setFail(reVo);
        reVo.setMessage("邮箱验证码发送失败");
        return reVo;
    }
    
    @Override
    public VoResponse sendCellphoneCode(String cellphone) {
        VoResponse reVo = new VoResponse();
    	User user = this.getUser();
    	if(user == null) {
    		//验证存在的手机号用户
    		BusUser bu = busUserMapper.findByCellphone(cellphone);
    		if (null == bu) {
    		    SysUser su = sysUserMapper.findByCellphone(cellphone);
    		    if (null == su) {
                    reVo.setFail(reVo);
                    reVo.setMessage("该手机号码未在平台使用，请尝试邮件重置密码");
                    return reVo;
                }
    		}
    	}
        String id = String.valueOf((int)((Math.random()*9+1)*1000));
        String smsMessage = SmsSender.makeSmsMsg("【生产力促进中心】验证码:%0%。您正在%1%，泄露有风险，请妥善保管", new String[] {id, "重置密码或更改手机号码"});
        if (smsSender.sendSms(cellphone, smsMessage)) {
            this.getRedisTemplate().opsForValue().set("mcc:" + cellphone, id, 300, TimeUnit.SECONDS);
            reVo.setMessage("短信验证码已发送");
            return reVo;
        }
//        SmsUtil sms = new SmsUtil();
//        ResponseEntity<String> responseEntity = null;
//        try {
//            responseEntity = sms.sendSmsByTemplate(cellphone, id);
//        } catch (Exception e) {
//            e.printStackTrace();
//            reVo.setFail(reVo);
//            reVo.setMessage("发送短信验证码异常");
//            return reVo;
//        }
//        if (responseEntity.getStatusCode() == HttpStatus.OK) {
//            this.getRedisTemplate().opsForValue().set("mcc:" + cellphone, id, 360, TimeUnit.SECONDS);
//            reVo.setMessage("短信验证码已发送");
//            return reVo;
//        }
        reVo.setFail(reVo);
        reVo.setMessage("短信验证码发送失败");
        return reVo;
    }

    @Override
    public boolean sendEmailActivate(String email) {
        UUID uuid = UUID.randomUUID();
        //String url = "http://localhost:8080/xtcx/user/activate?activateId=" + uuid.toString();
        //String url = "http://106.14.172.38:8990/jmrh/#/xtcx/user/activate?activateId=" + uuid.toString();
        String url = "<a href=\"" + activateServer + "/xtcx/user/activate?activateId="+uuid.toString()+"\" target=\"_blank\">" + activateServer + "/xtcx/user/activate?activateId=" + uuid.toString() + "</a>";
        if(!emailService.sendRegisterEmailHtml(email, url)) {
            return false;
        }
        this.getRedisTemplate().opsForValue().set(uuid.toString(), email, 30, TimeUnit.MINUTES);
        return true;
    }

    @Override
    public VoResponse register(BusUser user) {
        VoResponse voRes = new VoResponse();
        //检查邮箱是否已经注册
        BusUser e = busUserMapper.findByEmail(user.getEmail());
        if(e != null) {
            voRes.setFail(voRes);
            voRes.setMessage("邮箱已经被注册");
            return voRes;
        }
        e = busUserMapper.findByCode(user.getCode());
        // 查询到账户并且已经激活或认证的
        if(e != null) {
            if (0 != e.getCheckStatus()) {
                voRes.setFail(voRes);
                String msg = null;
                if(user.getUserType() == 1) {
                    msg = "身份证号";
                }else if(user.getUserType() == 2) {
                    msg = "统一社会信用代码";
                }else if(user.getUserType() == 3) {
                    msg = "统一社会信用代码";
                }else if(user.getUserType() == 4) {
                    msg = "统一社会信用代码";
                }
                voRes.setMessage(msg + "已经被注册");
                return voRes;
            } else {
                busUserMapper.delUserRoles(e.getId());
                busUserMapper.del(e.getId());
            }
        }
        if(!this.sendEmailActivate(user.getEmail())) {
            voRes.setFail(voRes);
            voRes.setMessage("邮件发送失败，请检查输入的邮箱是否正确");
            return voRes;
        }
//        user.setUserName(user.getEmail().split("@")[0]);
        user.setUserName(user.getEmail());
        user.setCheckStatus(0);//未激活
        String md5Password = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());//md5加密
        user.setPassword(md5Password);
        int result = busUserMapper.insert(user);
        List<SysRole> roles = null;
        if (1 == user.getUserType()) {
            roles = sysRoleMapper.findRolesByType(UserTypeEnum.Expert.theName());
        } else if (2 == user.getUserType()) {
            roles = sysRoleMapper.findRolesByType(UserTypeEnum.Enterprise.theName());
        } else if (3 == user.getUserType()) {
            roles = sysRoleMapper.findRolesByType(UserTypeEnum.Service.theName());
        } else if (4 == user.getUserType()) {
            roles = sysRoleMapper.findRolesByType(UserTypeEnum.College.theName());
        } else {
        }
        BusUser bu = busUserMapper.findByEmail(user.getEmail());
        bu.setRoles(roles);
        if (null != roles && 0 < roles.size()) {
            busUserMapper.delUserRoles(bu.getId());
            busUserMapper.addUserRoles(bu);
        }
        if(result > 0) {
            voRes.setData(user);
            return voRes;
        }
        return voRes;
    }

    @Override
    public VoResponse activate(String uuid) {
        VoResponse voRes = new VoResponse();
        Object obj = this.getRedisTemplate().opsForValue().get(uuid);
        if(!StringUtils.isEmpty(obj)){
            String email = obj.toString();
            BusUser user = busUserMapper.findByEmail(email);
            if(user != null) {
                user.setCheckStatus(1);
                int result = busUserMapper.update(user);
                this.getRedisTemplate().delete(uuid);
                if(result > 0) {
                    //激活成功后自动登录
                    HttpSession session = getSession();
                    User e = new User();
                    e.setUserId(user.getId());
                    e.setUserName(user.getUserName());
                    e.setUserType(user.getUserType());
                    e.setToken(session.getId());
                    e.setEmail(user.getEmail());
                    e.setCellphone(user.getCellphone());
                    e.setName(user.getName());
                    e.setCode(user.getCode());
                    e.setCheckStatus(user.getCheckStatus());
                    this.createRedisUser(e);
                    voRes.setData(e);
                    voRes.setMessage(obj + "激活成功");
                    // 增加和对接的关联
                    jmsMessagingTemplate.convertAndSend(refUserMeetingQueue, e);
                }else {
                    voRes.setMessage(obj + "激活失败");
                }
            }
        }else {
            voRes.setFail(voRes);
            voRes.setMessage("激活失败");
        }
        return voRes;
    }

    @Override
    public VoResponse saveOrUpdate(SysUser user) {
        VoResponse voRes = new VoResponse();
        int result = 0;
        SysUser e = sysUserMapper.findByUserame(user.getUserName());
        SysUser e1 = sysUserMapper.findByCellphone(user.getCellphone());
        SysUser e2 = sysUserMapper.findByEmail(user.getEmail());
        if(user.getId() == null) {//add
            if(e != null) {
                voRes.setFail(voRes);
                voRes.setMessage("用户名已被使用");
                return voRes;
            }
            if(e1 != null) {
                voRes.setFail(voRes);
                voRes.setMessage("手机号码已被使用");
                return voRes;
            }
            if(e2 != null) {
                voRes.setFail(voRes);
                voRes.setMessage("邮箱已被使用");
                return voRes;
            }
            String md5Password = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());//md5加密
            user.setPassword(md5Password);
            user.setCreater(this.getUserName());
            user.setStatus(1);
            result = sysUserMapper.insert(user);
            
        }else {
            SysUser oldUser = sysUserMapper.findById(user.getId());
//            if(!oldUser.getPassword().equals(user.getPassword())) {
//                String md5Password = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());//md5加密
//                user.setPassword(md5Password);
//            }
//            if(!oldUser.getUserName().equals(user.getUserName())) {
//                if(e1 != null) {
//                    voRes.setFail(voRes);
//                    voRes.setMessage("用户名已被使用");
//                    return voRes;
//                }
//            }
            if(!oldUser.getCellphone().equals(user.getCellphone())) {
                if(e1 != null) {
                    voRes.setFail(voRes);
                    voRes.setMessage("手机号码已被使用");
                    return voRes;
                }
            }
            if(!oldUser.getEmail().equals(user.getEmail())) {
                if(e2 != null) {
                    voRes.setFail(voRes);
                    voRes.setMessage("邮箱已被使用");
                    return voRes;
                }
            }
            oldUser.setEmail(user.getEmail());
            oldUser.setCellphone(user.getCellphone());
            oldUser.setUpdater(this.getUserName());
            result = sysUserMapper.update(oldUser);
        }
        List<SysRole> roles = user.getRoles();
        if(roles != null && roles.size() > 0) {//add role
            result = sysUserMapper.delUserRoles(user.getId());
            result = sysUserMapper.addUserRoles(user);
        }else if(roles != null && roles.size() == 0){
            result = sysUserMapper.delUserRoles(user.getId());
        }
        voRes.setData(result);
        return voRes;
        
    }

    private String decryptPassword(String pwd) {
        //String algorithmStr = "AES/CBC/PKCS5Padding";
        byte[] encPwdBytes = WzEncryptUtil.base64ToByteArr(pwd);
        if (null != encPwdBytes) {
            try {
                Cipher cipher = Cipher.getInstance(defAesAlgorithmStr);
                IvParameterSpec iv = new IvParameterSpec(defAesIv.getBytes("UTF-8"));
                cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(defAesKey.getBytes(), "AES"), iv);
                byte[] decryptBytes = cipher.doFinal(encPwdBytes);
                return new String(decryptBytes);
            } catch (Exception ex) {
                return null;
            }
        } else {
            return null;
        }
    }

    @Override
    public VoResponse signIn(String username, String password, boolean isAdmin) {
        VoResponse voRes = new VoResponse();
        Integer isForbid = this.getLoginForbidFlag(username);
        if (1 == isForbid) {
            voRes.setCode(10001);
            voRes.setSuccess(false);
            voRes.setMessage("您的账号已被冻结，请24小时后再试");
        }
        String pwdStr = password;
        // TODO:
        //String pwdStr = decryptPassword(password);
        if (WzStrUtil.isBlank(pwdStr)) {
            // 只有5次试错机会，否则需要被冻结24小时
            int cnt = this.setLoginFailTimes(username,defLoginForbidTime);
            voRes.setCode(10001);
            voRes.setSuccess(false);
            if (4 < cnt) {
                voRes.setMessage("用户名或者密码错误，您的账号已被冻结，请24小时后再试");
            } else {
                voRes.setMessage("用户名或者密码错误，再输错" + (5 - cnt) + "次用户名或密码，账号将被冻结24小时");
            }
            return voRes;
        }
        String md5Password = DigestUtils.md5DigestAsHex(pwdStr.getBytes());//md5加密
        if(isAdmin) {
            SysUser user = sysUserMapper.findByUserame(username);
            if(user != null && user.getPassword().equals(md5Password)) {
                if(user.getStatus() == 0) {
                    voRes.setCode(10003);
                    voRes.setSuccess(false);
                    voRes.setMessage("管理账户被禁用");
                    return voRes;
                }
                HttpSession session = getSession();
                User e = new User();
                e.setUserId(user.getId());
                e.setUserName(user.getUserName());
                //判断管理员角色
                List<SysRole> roles = sysRoleMapper.findRolesByUserId(user.getId());
                int ut = 103;
                for (SysRole sr : roles) {
                    if ("superAdmin".equals(sr.getRoleName())) {
                        ut = 0;
                        break;
                    } else if ("webAdmin".equals(sr.getRoleName()) && 101 < ut) {
                        ut = 101;
                    } else if ("cityAdmin".equals(sr.getRoleName()) && 102 < ut) {
                        ut = 102;
                    } else if ("zoneAdmin".equals(sr.getRoleName())) {
                        ut = 103;
                    } else {
                        ut = 103;
                    }
                }
                e.setUserType(ut);
                /*if(user.getRoles() != null) {
                    SysRole role = user.getRoles().get(0);
                    switch(role.getRoleName()) {
                        case "超级管理员" :
                            e.setUserType(-2); break;
                        case "网站管理员" :
                            e.setUserType(-1); break;
                        case "地方管理员" :
                            e.setUserType(0); break;
                    }
                }*/
                if(password.equals("123456")) {
                	e.setCheckStatus(-1);//初始密码提示
                }
                e.setToken(session.getId());
                e.setEmail(user.getEmail());
                e.setCellphone(user.getCellphone());
                this.createRedisUser(e);
                this.removeLoginFailTimesAndForbidFlag(username);
                voRes.setData(e);
                return voRes;
            }
        }else {
            BusUser user = busUserMapper.findByEmail(username);//邮箱
            if(user != null && user.getPassword().equals(md5Password)) {
                if(user.getCheckStatus() == 0) {
                    voRes.setCode(10002);
                    voRes.setSuccess(false);
                    voRes.setMessage("用户未激活,请重新发送邮箱进行激活！");
                    return voRes;
                }
                if(user.getStatus() == 0) {
                    voRes.setCode(10003);
                    voRes.setSuccess(false);
                    voRes.setMessage("用户被禁用");
                    return voRes;
                }
                HttpSession session = getSession();
                User e = new User();
                e.setUserId(user.getId());
                e.setUserName(user.getUserName());
                e.setUserType(user.getUserType());
                e.setToken(session.getId());
                e.setEmail(user.getEmail());
                e.setCellphone(user.getCellphone());
                e.setName(user.getName());
                e.setCode(user.getCode());
                e.setCheckStatus(user.getCheckStatus());
                this.createRedisUser(e);
                this.removeLoginFailTimesAndForbidFlag(username);
                voRes.setData(e);
                // 增加和对接的关联
                jmsMessagingTemplate.convertAndSend(refUserMeetingQueue, e);
                return voRes;
            }
        }
        // 只有5次试错机会，否则需要被冻结24小时
        int cnt = this.setLoginFailTimes(username, defLoginForbidTime);
        voRes.setCode(10001);
        voRes.setSuccess(false);
        if (4 < cnt) {
            voRes.setMessage("用户名或者密码错误，您的账号已被冻结，请24小时后再试");
        } else {
            voRes.setMessage("用户名或者密码错误，再输错" + (5 - cnt) + "次用户名或密码，账号将被冻结24小时");
        }
        return voRes;
    }
    
    @Override
    public void signOut() {
        this.destroyedRedisUser();
    }

    @Override
    public SysUser getUserByUsername(String username) {
        SysUser user = sysUserMapper.findByUserame(username);
        return user;
    }

    @Override
    public PageInfo<SysUser> getPageByCondition(VoQuery user, int pageNum, int pageSize, String orderBy) {
        Page<SysUser> page = PageHelper.startPage(pageNum, pageSize);
        if(StringUtils.isEmpty(orderBy)) {
            PageHelper.orderBy("create_time desc");
        }else {
            PageHelper.orderBy(orderBy);
        }
        sysUserMapper.findByCondition(user);
        PageInfo<SysUser> info = new PageInfo<SysUser>(page);
        return info;
    }

    /**
     * 删除角色，删除用户
     * @param id
     * @return
     */
    @Override
    public int del(String id) {
        sysUserMapper.delUserRoles(id);
        int result = sysUserMapper.del(id);
        return result;
    }

    @Override
    public List<SysUser> getAll() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public List<SysMenu> getCurrentUserMenus() {
    	List<SysMenu> list =  null;
        List<SysRole> roles = null;
        User user = this.getUser();
        if(user != null) {
        	switch(user.getUserType()) {
	            case 0:
	//                SysUser sysuser = sysUserMapper.findById(user.getUserId());
	//            	if(sysuser != null && sysuser.getRoles() != null) {
	//                    list =  this.getUserMenuById(sysuser.getRoles());
	//                }
	                roles = sysRoleMapper.findRolesByUserId(user.getUserId());
	                break;
	            case 1:
	            	roles = sysRoleMapper.findRolesByType(UserTypeEnum.Expert.theName());
	                break;
	            case 2:
	            	roles = sysRoleMapper.findRolesByType(UserTypeEnum.Enterprise.theName());
	                break;
	            case 3:
	            	roles = sysRoleMapper.findRolesByType(UserTypeEnum.Service.theName());
	                break;
	            case 4:
	            	roles = sysRoleMapper.findRolesByType(UserTypeEnum.College.theName());
	                break;
	            case 5:
	            	roles = sysRoleMapper.findRolesByType(UserTypeEnum.Military.theName());
	                break;
                case 101:
                    roles = sysRoleMapper.findRolesByUserId(user.getUserId());
                    break;
                case 102:
                    roles = sysRoleMapper.findRolesByUserId(user.getUserId());
                    break;
                case 103:
                    roles = sysRoleMapper.findRolesByUserId(user.getUserId());
                    break;
                default:
                    roles = sysRoleMapper.findRolesByUserId(user.getUserId());
                    break;
	        }
        }else {
        	roles = sysRoleMapper.findRolesByType("visiter");
        }
        //list =  this.getUserMenuById(roles);

//        list = sysMenuMapper.findByRoleIds(this.tranRoleIds(roles));
        List<SysMenu> myMenus = new LinkedList<SysMenu>();
//        if(list != null && list.size() > 0) {
//        	for(SysMenu menu : list) {
//				if(StringUtils.isEmpty(menu.getParentId())) {//父目录顺序
//					if(menu.getIsMenu() != null) {
//						menu.setMenuLevel(1);
//						setTreeSub(menu, list);
//						myMenus.add(menu);
//					}
//				}
//			}
//        }
        List<SysMenu> treeList = sysMenuMapper.findMenuTree();
        if (null != roles && 0 < roles.size()) {
            list = sysMenuMapper.findSubMenuByRoleIds(this.tranRoleIds(roles));
            if(list != null && list.size() > 0) {
                for(SysMenu mainMenu : treeList) {
                    if(StringUtils.isEmpty(mainMenu.getParentId())) {//父目录顺序
                        if(mainMenu.getIsMenu() != null) {
                            mainMenu.setMenuLevel(1);
                            setTreeSub(mainMenu, list);
                            myMenus.add(mainMenu);
                        }
                    }
                }
            }
            for (int m = myMenus.size() - 1; m >= 0; m--) {
                if ((null == myMenus.get(m).getMenus() || 0 == myMenus.get(m).getMenus().size()) && !"我的待办".equals(myMenus.get(m).getMenuName())) {
                    myMenus.remove(m);
                }
            }
            this.setMenu(myMenus, null);
        }

//        if(list != null && list.size() > 0) {
//        	for(SysMenu menu : list) {
//				if(StringUtils.isEmpty(menu.getParentId())) {//父目录顺序
//					if(menu.getIsMenu() != null) {
//						menu.setMenuLevel(1);
//						setTreeSub(menu, list);
//						myMenus.add(menu);
//					}
//				}
//			}
//        }
//        for (int i  = myMenus.size() -1; i >= 0; i--) {
//            if (!hasNoMenuLeaf(myMenus.get(i))) {
//                myMenus.remove(i);
//            }
//        }
//        removeNoMenuLeaf(myMenus);
        return myMenus;
    }

    private boolean hasNoMenuLeaf(SysMenu m) {
        boolean isHasNoMenuLeaf = false;
        if ("1".equals(m.getIsMenu())) {
            if (null != m.getMenus() && 0 < m.getMenus().size()) {
                for (int j = m.getMenus().size() - 1; j >= 0; j--) {
                    if (hasNoMenuLeaf(m.getMenus().get(j))) {
                        isHasNoMenuLeaf = true;
                        break;
                    } else {
//                        m.getMenus().remove(j);
                    }
                }
                return isHasNoMenuLeaf;
            } else {
                return true;
            }
        } else {
            return true;
        }
    }

    private void removeNoMenuLeaf(List<SysMenu> ms) {
        for (int k = ms.size() - 1; k >= 0; k--) {
            if ("1".equals(ms.get(k).getIsMenu())) {
                if (null != ms.get(k).getMenus() && 0 < ms.get(k).getMenus().size()) {
                    removeNoMenuLeaf(ms.get(k).getMenus());
                }
            } else {
                ms.remove(k);
            }
        }
    }

    private String tranRoleIds(List<SysRole> roles) {
    	StringBuilder sql = new StringBuilder();
    	if (null != roles && 0 < roles.size()) {
            for(SysRole role : roles) {
                sql.append("'").append(role.getId()).append("',");
            }
            sql.deleteCharAt(sql.length() - 1);
        }
    	return sql.toString();
    }
    
    void setTreeSub(SysMenu par, List<SysMenu> listAll) {
		for(SysMenu menu : listAll) {
			if(StringUtils.isEmpty(menu.getParentId())) {//父目录
				continue;
			} else if (menu.getId().equals(par.getId())) {
			    continue;
            } else if(menu.getParentId().equals(par.getId())) {//子目录
				if(par.getMenus() == null) {
					par.setMenus(new LinkedList<SysMenu>());
				}
				menu.setMenuLevel(par.getMenuLevel() + 1);
				par.getMenus().add(menu);
				setTreeSub(menu, listAll);
			} 
		}
	}

    public List<SysMenu> getUserMenuById(List<SysRole> roles){
        //SysUser user = sysUserMapper.findById(userId);
        
        //List<SysRole> roles = user.getRoles();
        List<SysMenu> myMenus = new ArrayList<SysMenu>();
        List<SysMenu> allMenus = sysMenuMapper.findTree();
        for(SysRole role : roles){
            if(role.getRoleName().equals("超级管理员")){//管理员获取所有菜单
                return allMenus;
            }
            List<SysMenu> menus = role.getMenus();
            if(menus == null ) {
            	continue;
            }
            if(myMenus.size() == 0){
                myMenus.addAll(menus);
                continue;
            }
            boolean flag = false;
            for(SysMenu e : menus){
                flag = false;
                for(SysMenu menu : myMenus){
                    if(e.getId().equals(menu.getId())){
                        flag = true;
                        continue;
                    }
                }
                if(!flag){
                    myMenus.add(e);
                }
            }
        }
        transMenus(myMenus, allMenus);
        return allMenus;
    }

    /**
     * 转前端树形菜单数据
     * @param list
     * @param lastMenu
     * @return
     */
    private List<SysMenu> setMenu(List<SysMenu> list, SysMenu lastMenu){
        Iterator<SysMenu> it = list.iterator();
        List<SysMenu> listnull = new ArrayList<>();
        while (it.hasNext()) {
            SysMenu menu = it.next();
            menu.setLeaf(true);
            if(menu.getMenus() != null && menu.getMenus().size() > 0 && menu.getMenuLevel() < 1000){
                boolean isLeafMenu = true;
                for (SysMenu subMenu : menu.getMenus()) {
                    if ("1".equals(subMenu.getIsMenu())) {
                        isLeafMenu = false;
                        break;
                    }
                }
                menu.setLeaf(isLeafMenu);
                setMenu(menu.getMenus(), menu);
            }else if(menu.getMenuLevel() == 1000){
                lastMenu.setAuthmenus(list);
                lastMenu.setMenus(listnull);
                lastMenu.setLeaf(true);
            }
        }
        return list;
    }
    
    /**
     * 迭代出菜单树形的目录
     * @param myMenus 用户的菜单列表
     * @param menus 所有的树形菜单
     */
    private void transMenus(List<SysMenu> myMenus, List<SysMenu> menus){
        Iterator<SysMenu> itMenu = menus.iterator();
        while(itMenu.hasNext()){
            SysMenu menu = itMenu.next();
            boolean flag = false;
            for(SysMenu mymenu : myMenus){
                if(menu.getId().equals(mymenu.getId())){
                    flag = true;
                    break;
                }
            }
            if(!flag){
                itMenu.remove();
                flag = false;
                continue;
            }
            if(menu.getMenus() != null && menu.getMenus().size() > 0){
                transMenus(myMenus, menu.getMenus());
            }
        }
    }
    
    @Override
    public PageInfo<BusUser> getPageBusUserByCondition(VoQuery query, int pageNum, int pageSize, String orderBy) {
        Page<BusUser> page = PageHelper.startPage(pageNum, pageSize);
        if(StringUtils.isEmpty(orderBy)) {
            PageHelper.orderBy("create_time desc");
        }else {
            PageHelper.orderBy(orderBy);
        }
        busUserMapper.findByCondition(query);
        PageInfo<BusUser> info = new PageInfo<BusUser>(page);
        if (null != info.getList() || 0 < info.getList().size()) {
            for (int i = 0; i < info.getList().size(); i++) {
                if (WzStrUtil.isNotBlank(info.getList().get(i).getCountry())) {
                    String tmpStr = info.getList().get(i).getCountry();
                    if (tmpStr.startsWith("\"")) {
                        tmpStr = tmpStr.substring(1);
                    }
                    if (tmpStr.endsWith("\"")) {
                        tmpStr = tmpStr.substring(0, tmpStr.length() - 1);
                    }
                    info.getList().get(i).setCountry(tmpStr);
                }
            }
        }
        return info;
    }

    
    int saveEnterprise(JSONObject json){
        return 0;
    }

    @Override
    public Object getRedisUser(String userId) {
        Map<String, Object> map = new HashMap<String, Object>();
        RedisOperations<String, Object> redis = this.getRedisTemplate().opsForValue().getOperations();
        if(redis.hasKey(userId)) {
            String token = (String) this.getRedisTemplate().opsForValue().get(userId);
            map.put("token", token);
            if(redis.hasKey(token)) {
                map.put("user", this.getRedisTemplate().opsForValue().get(token));
            }
        }
        String id = this.getSession().getId();
        Object obj = this.getRedisTemplate().opsForValue().get(id);
        map.put("currUser", obj);
        return map;
    }

    @Override
    public BusUser getUserByEmail(String email) {
        return busUserMapper.findByEmail(email);
    }

    @Override
    public BusUser getUserByCellPhone(String phone) {
        return busUserMapper.findByCellphone(phone);
    }

    @Override
    public VoResponse exportBusUsers(VoQuery userParam, OutputStream out) {
        VoResponse voRes = new VoResponse();
        User u = getUser(userParam.getTokenStr());
        if (null == u) {
            voRes.setFail(voRes);
            voRes.setMessage("未登录或登录已超时");
            return voRes;
        }
        List<BusUser> busUserLs = busUserMapper.findByCondition(userParam);
        if (null == busUserLs || 0 == busUserLs.size()) {
            voRes.setFail(voRes);
            voRes.setMessage("未查询到待导出的注册用户信息");
            return voRes;
        }
        ExcelUtil.writeBusUserExcel(busUserLs, out);
        return null;
    }

    /**
     * 删除注册用户
     * @param id
     * @return
     */
    @Override
    public int delBusUser(String id) {
        int del = busUserMapper.del(id);
        return del;
    }
}
